<template>
    <el-menu class="header-menu" mode="horizontal" background-color="rgba(10,100,168,0.8)" text-color="#fff" active-text-color="#fff" :ellipsis="false">
        <el-menu-item index="1">
            <lemon-image :src="logo" style="width: 60px; height: 60px" />
            <h2 class="menu-title animate__animated animate__bounce">{{ title }}</h2>
        </el-menu-item>
        <el-menu-item index="2" @click="onCollapse">
            <lemon-icon :size="50" :icon="collapse ? 'Expand' : 'Fold'" />
        </el-menu-item>
        <el-menu-item index="3">
            <lemon-image :src="avatar" style="width: 60px; height: 60px; border-radius: 30px" />
        </el-menu-item>
        <el-sub-menu index="4">
            <template #title><lemon-icon :size="50" icon="Menu" /></template>
            <el-menu-item index="4-1" @click="onUserInfo">个人资料</el-menu-item>
            <el-menu-item index="4-2" @click="onUpdatePassword">修改密码</el-menu-item>
            <el-menu-item index="4-3" @click="onSendNotice">发布通知</el-menu-item>
        </el-sub-menu>
        <el-tooltip class="box-item" effect="dark" content="通知" placement="bottom" :hide-after="0">
            <el-menu-item index="5" @click="onNoticeList">
                <lemon-icon :size="50" :icon="noticeCount == 0 ? 'BellFilled' : null" />
                <el-badge :value="noticeCount" class="animate__animated animate__flash" style="margin-top: 18px" v-if="noticeCount != 0">
                    <lemon-icon :size="30" icon="BellFilled" style="bottom: 11px" />
                </el-badge>
            </el-menu-item>
        </el-tooltip>
        <el-tooltip class="box-item" effect="dark" :content="isFullscreen ? '退出全屏' : '全屏'" placement="bottom" :hide-after="0">
            <el-menu-item index="6" @click="onFullScreen">
                <component :is="isFullscreen ? shrinkscreen() : fullscreen()" />
            </el-menu-item>
        </el-tooltip>
        <el-tooltip class="box-item" effect="dark" content="退出登录" placement="bottom-start" :hide-after="0">
            <el-menu-item index="7" @click="onLogout" :key="logoutKey">
                <component :is="logout()" />
            </el-menu-item>
        </el-tooltip>
    </el-menu>

    <!-- 个人资料 -->
    <lemon-dialog v-model="dialogUserInfo" dialog-title="个人资料" :dialog-footer="true" @on-submit="onUserInfoSubmit" @on-cancel="onUserInfoCancel" @on-before-close="onUserInfoCancel">
        <lemon-form :form-model="userInfoModel" :form-item="userInfoFormItem" class="lemon-form-class" :form-button="false" ref="lemonFormRef" />
    </lemon-dialog>

    <!-- 修改密码 -->
    <lemon-dialog v-model="dialogUpdatePassword" dialog-title="修改密码" :dialog-footer="true" @on-submit="onUpdatePasswordSubmit" @on-cancel="onUpdatePasswordCancel" @on-before-close="onUpdatePasswordCancel">
        <lemon-form :form-model="updatePasswordModel" :form-item="updatePasswordFormItem" class="lemon-form-class" :form-button="false" ref="lemonFormRef" />
    </lemon-dialog>

    <!-- 发布通知 -->
    <lemon-dialog v-model="dialogSendNotice" dialog-title="发布通知" :dialog-footer="true" @on-submit="onSendNoticeSubmit(false)" @on-cancel="onSendNoticeCancel" @on-before-close="onSendNoticeCancel">
        <lemon-form :form-model="sendNoticeModel" :form-item="sendNoticeFormItem" class="lemon-form-class" :form-button="false" ref="lemonFormRef" />
        <!-- 保存按钮 -->
        <template #centerBtn>
            <el-button type="info" @click="onSendNoticeSubmit(true)">保存</el-button>
        </template>
    </lemon-dialog>

    <!-- 消息列表 -->
    <div class="notice-drawer">
        <el-drawer v-model="noticeShowDrawer" title="通知" direction="rtl" size="30%">
            <el-tabs v-model="noticeActive" stretch lazy type="border-card" @tab-click="onNoticeTab">
                <el-tab-pane label="未读" name="unread"><component :is="renderNoticeTable" /></el-tab-pane>
                <el-tab-pane label="已读" name="read"><component :is="renderNoticeTable" /></el-tab-pane>
                <el-tab-pane label="我的" name="mine"><component :is="renderNoticeTable" /></el-tab-pane>
            </el-tabs>
        </el-drawer>
    </div>

    <!-- 消息详情 -->
    <lemon-dialog v-model="dialogNoticeInfo" :dialog-title="noticeInfoModel?.title" @on-before-close="onNoticeInfoCancel">
        <lemon-form :form-model="noticeInfoModel" :form-item="noticeInfoFormItem" class="lemon-form-class" :form-button="false" ref="lemonFormRef" :form-is-show-empty="false" />
    </lemon-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, inject, onMounted, onBeforeUnmount, computed, h } from "vue";
import { ElTable, ElTableColumn, type TabsPaneContext } from "element-plus";
import logo from "@/assets/img/logo.png";
import { SSE, request } from "@/utils/sse";
import { genderOptions, statusOptions, fullscreen, shrinkscreen, logout } from "@/utils/common";
import { useFullscreen } from "@/utils/full-screen";

//获取自定义全局方法
const { authStore, emitter, http, box, rule, encrypt } = inject<any>("method");

//全屏配置
const { isFullscreen, toggleFullscreen } = useFullscreen();
const onFullScreen = () => {
    toggleFullscreen();
};

//读取全局配置文件中的标题
const title: any = ref<string>(import.meta.env.VITE_APP_TITLE);

//头像图片
const avatar = ref<string | undefined>(undefined);

//获取头像图片
const getAvatar = async () => (avatar.value = await http.get("getCurrentUserAvatar"));

//折叠菜单，默认展开
const collapse = ref<boolean>(authStore.menuCollapse);

const onCollapse = () => {
    collapse.value = !collapse.value;
    authStore.setMenuCollapse(collapse.value);
    emitter.emit("on-menu-collapse", collapse.value);
};

//是否展示个人信息弹窗
const dialogUserInfo = ref<boolean>(false);

//个人资料数据
const userInfoModel = reactive<any>({
    id: "",
    username: "",
    name: "",
    phone: "",
    sex: null,
    email: "",
    birthday: "",
    avatar: "",
    provinceId: null,
    cityId: null,
    countyId: null,
    address: "",
    lastLoginIp: "",
    lastLoginTime: "",
    createBy: "",
    createTime: "",
    updateBy: "",
    updateTime: "",
    status: null,
    roleNameList: [],
});

//个人资料表单
const userInfoFormItem = reactive({
    username: { label: "用户名", type: "input", readonly: true },
    name: { label: "姓名", type: "input", rules: rule.require.input("姓名") },
    email: { label: "邮箱", type: "input", rules: rule.email() },
    phone: { label: "手机号", type: "input", rules: rule.phone() },
    sex: { label: "性别", type: "select", options: genderOptions, rules: rule.require.select() },
    birthday: { label: "生日", type: "date", style: { width: "100%" }, rules: rule.require.select() },
    countyId: { label: "城市", type: "city", rules: rule.require.select() },
    address: { label: "地址", type: "input", rules: rule.require.input("地址") },
    avatar: { label: "头像", type: "image-upload", uploadUrl: "uploadCurrentUserAvatar", maxSize: "2mb" },
    roleNameList: { label: "角色", type: "tag", readonly: true },
    status: { label: "状态", type: "select", options: statusOptions, readonly: true },
    createBy: { label: "创建人", type: "input", readonly: true },
    createTime: { label: "创建时间", type: "datetime", readonly: true, style: { width: "100%" } },
    updateBy: { label: "更新人", type: "input", readonly: true },
    updateTime: { label: "更新时间", type: "datetime", readonly: true, style: { width: "100%" } },
});

//form表单组件
const lemonFormRef: any = ref(null);

//提交个人资料对话框
const onUserInfoSubmit = async () => {
    if (!lemonFormRef.value?.formRef()) return;
    const data = await lemonFormRef.value?.formRef().validate((valid: any, _fields: any) => {
        if (valid) {
            return http.put("updateCurrentUser", userInfoModel).then((data: any) => {
                if (data?.success) {
                    emitter.emit("msg-success", data.data);
                }
            });
        }
    });
    if (data) {
        onUserInfoCancel();
        //判断是否修改了头像
        if (userInfoModel.avatar != avatar.value) {
            getAvatar();
        }
        emitter.emit("home-header-get-user");
    }
};

//取消个人资料对话框
const onUserInfoCancel = () => {
    //重置表单
    lemonFormRef.value?.resetFields();
    dialogUserInfo.value = false;
};

//个人资料
const onUserInfo = async () => {
    dialogUserInfo.value = true;
    const data = await http.get("getCurrentUser");
    Object.keys(userInfoModel).forEach((item: any) => (userInfoModel[item] = data[item]));
};

//修改密码对话框
const dialogUpdatePassword = ref<boolean>(false);

//修改密码对话框提交
const onUpdatePasswordSubmit = async () => {
    if (!lemonFormRef.value?.formRef()) return;
    const data = await lemonFormRef.value?.formRef().validate((valid: any, _fields: any) => {
        if (valid) {
            const param = {
                oldPassword: encrypt(updatePasswordModel.oldPassword),
                newPassword: encrypt(updatePasswordModel.newPassword),
                confirmPassword: encrypt(updatePasswordModel.confirmPassword),
            };
            return http.put("updateCurrentUserPassword", param).then((data: any) => {
                if (data?.success) {
                    emitter.emit("msg-warning", { message: data.data, duration: 3000 });
                    authStore.clear();
                    //清空路由
                    emitter.emit("router-remove");
                    setTimeout(() => emitter.emit("router-push", "/"), 3000);
                }
            });
        }
    });
    if (data) {
        onUpdatePasswordCancel();
    }
};

//修改密码对话框取消
const onUpdatePasswordCancel = () => {
    lemonFormRef.value?.resetFields();
    dialogUpdatePassword.value = false;
};

//修改密码表单
const updatePasswordModel = reactive<any>({
    oldPassword: "",
    newPassword: "",
    confirmPassword: "",
});

//修改密码表单验证规则
const updatePasswordFormItem = reactive({
    oldPassword: { label: "旧密码", type: "password", rules: rule.require.input("旧密码") },
    newPassword: { label: "新密码", type: "password", rules: rule.require.input("新密码") },
    confirmPassword: { label: "确认密码", type: "password", rules: rule.require.input("确认密码") },
});

//修改密码
const onUpdatePassword = () => {
    dialogUpdatePassword.value = true;
    lemonFormRef.value?.resetFields();
};

const sendNoticeModel = reactive({
    userIdList: [],
    type: 1,
    title: "",
    content: "",
    remark: "",
});

const sendNoticeFormItem = reactive({
    type: {
        label: "类型",
        type: "radio",
        button: true,
        options: [
            { label: "通知", value: 1 },
            { label: "公告", value: 2 },
        ],
        size: "default",
        rules: rule.require.select(),
    },
    userIdList: { label: "用户", type: "tree-select", options: [], multiple: true, filterable: true, showCheckbox: true, checkStrictly: false, defaultExpandAll: true, rules: rule.require.select() },
    title: { label: "标题", type: "input", rules: rule.require.input("标题") },
    content: { label: "内容", type: "textarea", rows: 5, rules: rule.require.input("内容") },
    remark: { label: "备注", type: "textarea", rows: 3 },
});

//发送通知对话框
const dialogSendNotice = ref<boolean>(false);

//发送通知点击事件
const onSendNotice = async () => {
    //1.并行执行两个请求[加载路由,加载路由对应的资源信息]
    const [userIdList, noticeInfo] = await Promise.all([http.get("/getTreeClassUserByCurrent"), http.get("/getNoSubmitNotice")]);
    if (userIdList && userIdList.length > 0) {
        sendNoticeFormItem.userIdList.options = userIdList;
    }
    if (noticeInfo) {
        Object.assign(sendNoticeModel, noticeInfo);
    }
    dialogSendNotice.value = true;
};

//发送通知
const onSendNoticeSubmit = async (isSave: boolean) => {
    if (!lemonFormRef.value?.formRef()) return;
    const data = await lemonFormRef.value?.formRef().validate((valid: any, _fields: any) => {
        if (valid) {
            return http.post(`sendNotice`, { ...sendNoticeModel, isSave }).then((data: any) => {
                if (data?.success) {
                    emitter.emit("msg-success", data.data);
                }
            });
        }
    });
    if (data) {
        onSendNoticeCancel();
    }
};

//发送通知
const onSendNoticeCancel = () => {
    dialogSendNotice.value = false;
    lemonFormRef.value?.resetFields();
};

//消息数量
const noticeCount = ref(0);

//消息sse实例
const noticeCountInstance = ref<SSE | null>(null);

const getNoticeCountConnection = () => {
    noticeCountInstance.value = request(`getNoticeCountConnection?t=${Date.now()}`, (data: any) => {
        if (data.type === 2) {
            const count = parseInt(data.data);
            if (count === noticeCount.value) {
                return;
            }
            noticeCount.value = count;
        }
    });
    // noticeCountInstance.value = new SSE(`getNoticeCountConnection`, {
    //     params: { t: Date.now() },
    //     method: "GET",
    //     autoReconnect: true,
    //     onMessage: (data: any) => {
    //         console.log("SSE收到消息:", data);
    //         if (data.type === 2) {
    //             const count = parseInt(data.data);
    //             if (count === noticeCount.value) {
    //                 return;
    //             }
    //             noticeCount.value = count;
    //         }
    //     },
    // });
};

//是否展示通知
const noticeShowDrawer = ref<boolean>(false);

//默认展示未读
const noticeActive = ref<string>("unread");

//通知列表
const noticeList = ref<any[]>([]);

//渲染通知列表
const renderNoticeTable = computed(() => {
    return h(
        ElTable,
        {
            data: noticeList.value,
            style: { width: "100%" },
            border: true,
            height: "calc(100vh - 180px)",
            onRowClick: onNoticeRow,
        },
        () => [
            h(ElTableColumn, {
                prop: "createTime",
                label: "时间",
                align: "center",
                sortable: true,
                width: "180",
            }),
            h(ElTableColumn, {
                prop: "title",
                label: "标题",
                align: "center",
                "show-overflow-tooltip": true,
            }),
        ]
    );
});
//获取通知列表
const onNoticeList = async () => {
    noticeList.value = await http.get("getNotice", { type: noticeActive.value });
    noticeShowDrawer.value = true;
};

//切换通知列表
const onNoticeTab = async (pane: TabsPaneContext, _ev: Event) => {
    noticeList.value = await http.get("getNotice", { type: pane?.props?.name });
};

//通知详情
const dialogNoticeInfo = ref<boolean>(false);

//通知详情表单
const noticeInfoModel = reactive<any>({
    userList: [],
    title: "",
    content: "",
    type: null,
    remark: "",
    createBy: "",
    createTime: "",
});

//通知详情表单
const noticeInfoFormItem = reactive({
    type: {
        label: "类型",
        type: "radio",
        button: true,
        options: [
            { label: "通知", value: 1 },
            { label: "公告", value: 2 },
        ],
        readonly: true,
        size: "default",
    },
    userList: { label: "用户", type: "select", readonly: true, multiple: true, options: [] },
    content: { label: "内容", type: "textarea", readonly: true, rows: 5 },
    remark: { label: "备注", type: "textarea", readonly: true, rows: 3 },
    createBy: { label: "创建人", type: "input", readonly: true },
    createTime: { label: "创建时间", type: "datetime", readonly: true, style: { width: "100%" } },
});

//通知列表行点击事件
const onNoticeRow = async (row: any) => {
    const data = await http.get(`getNoticeById`, { id: row.id, type: noticeActive.value });
    Object.keys(noticeInfoModel).forEach((item: any) => (noticeInfoModel[item] = data[item]));
    dialogNoticeInfo.value = true;
};

//关闭触发
const onNoticeInfoCancel = () => {
    lemonFormRef.value?.resetFields();
    dialogNoticeInfo.value = false;
};

const logoutKey = ref<string>(`logoutKey-${new Date().getTime()}`);
//退出
const onLogout = () => {
    box.confirm(`确定要退出吗？`, "退出", async () => {
        const data = await http.post("logout");
        if (data?.success) {
            emitter.emit("msg-success", data?.data);
            noticeCountInstance.value?.disconnect();
            //清空路由
            emitter.emit("router-remove");
            setTimeout(() => {
                authStore.clear();
                emitter.emit("router-push", "/");
            }, 2000);
        }
    });
};

//挂载时执行
onMounted(async () => {
    Promise.all([Promise.resolve(getAvatar()), Promise.resolve(getNoticeCountConnection())]);
});

//卸载时执行
onBeforeUnmount(() => {
    noticeCountInstance.value?.disconnect();
});
</script>

<style scoped lang="less">
@import "@/assets/less/common.less";
.header-menu {
    width: 100%;
    .menu-title {
        padding-left: 10px;
        font-size: 24px;
    }
    :deep(.is-active) {
        border-bottom: 0 !important;
    }
}
.notice-drawer:deep(.el-drawer__header) {
    margin-bottom: 0px !important;
}
.notice-drawer:deep(.el-table .el-table__row:hover) {
    cursor: pointer;
    font-weight: bolder;
    color: #409eff;
}
.el-menu--horizontal > .el-menu-item:nth-child(2) {
    margin-right: auto;
}
</style>
